﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DesignPatternsConsole
{
    public class Singleton
    {
        private static Singleton instance = null;

        private Singleton() { }

        public static Singleton Instance
        {

            get
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }

                return instance;
            }
        }
    }

    public sealed class Singleton2
    {
        private static Singleton2 instance = null;
        private static readonly object obj = new object();

        private Singleton2() { }

        public Singleton2 Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (obj)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton2();
                        }                        
                    }
                }
                return instance;
            }
        }
    }
    public sealed class Singleton3
    {
        private static readonly Singleton3 instance = new Singleton3();

        /// <summary>
        /// 显式的静态构造函数用来告诉C#编译器在其内容实例化之前不要标记其类型
        /// </summary>
        static Singleton3() { }

        private Singleton3() { }

        public static Singleton3 Instance
        {
            get
            {
                return instance;
            }
        }
    }
    public sealed class Singleton4
    {
        private Singleton4() { }

        public static Singleton4 Instance { get { return Nested.instance; } }

        private class Nested
        {
            //Explicit static constructor to tell C# compiler
            //not to mark type as beforefieldinit
            static Nested()
            {

            }

            internal static readonly Singleton4 instance = new Singleton4();
        }

    }
    public sealed class Singleton5
    {
        private static readonly Lazy<Singleton5> lazy =
               new Lazy<Singleton5>(() => new Singleton5());

        public static Singleton5 Instance { get { return lazy.Value; } }

        private Singleton5() { }
    }
    public sealed class Singleton6
    {
        private static Singleton6 loader;
        internal Singleton6()
        {
        }      
        public static Singleton6 GetLoader()
        {
            if (loader == null)
            {
                Singleton6 sr = new Singleton6();
                Interlocked.CompareExchange<Singleton6>(ref loader, sr, null);
            }
            return loader;
        }

    }
}
